package cn.iocoder.yudao.module.erp.service.dp;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateTimeAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.dispatchvehicle.vo.DispatchVehicleSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpmsk.vo.DpMskPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpmsk.vo.DpMskSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dispatchvehicle.DispatchVehicleDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpMskDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpSignDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemMskDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.supplierfleet.SupplierFleetDO;
import cn.iocoder.yudao.module.erp.dal.mysql.dispatchvehicle.DispatchVehicleMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpMskMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpSignMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpitem.DpItemMskMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.supplierfleet.SupplierFleetMapper;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * ERP莫斯科仓库 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class DpMskServiceImpl implements DpMskService {

    @Resource
    private DpMskMapper dpMskMapper;
    @Resource
    private DpItemMskMapper dpItemMskMapper;
    @Resource
    private DispatchVehicleMapper dispatchVehicleMapper;
    @Resource
    private DpServiceImpl dpServiceImpl;
    @Resource
    private SupplierFleetMapper supplierFleetMapper;
    @Resource
    private DpSignMapper dpSignMapper;
    @Resource
    private DpMapper dpMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createDpMsk(DpMskSaveReqVO createReqVO) {
        // 插入
        DpMskDO dpMsk = BeanUtils.toBean(createReqVO, DpMskDO.class);
        dpMskMapper.insert(dpMsk);

        // 插入子表
        createDpItemMskList(dpMsk.getId(), createReqVO.getDpItemMsks());
        // 返回
        return dpMsk.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDpMsk(DpMskSaveReqVO updateReqVO) {
        // 更新
        DpMskDO updateObj = BeanUtils.toBean(updateReqVO, DpMskDO.class);
        dpMskMapper.updateById(updateObj);

        // 更新子表
        updateDpItemMskList(updateReqVO.getId(), updateReqVO.getDpItemMsks());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDpMsk(String id) {
        // 删除
        dpMskMapper.deleteById(id);

        // 删除子表
        deleteDpItemMskByNo(id);
    }

    @Override
    public DpMskDO getDpMsk(String id) {
        return dpMskMapper.selectById(id);
    }

//    @Override
//    public PageResult<DpMskDO> getDpMskPage(DpMskPageReqVO pageReqVO) {
//        return dpMskMapper.selectPage(pageReqVO);
//    }

    @Override
    public PageResult<DpMskDO> getDpMskPage(DpMskPageReqVO pageReqVO) {
        return dpMskMapper.getDpMskPage(pageReqVO);
    }

    @Override
    public PageResult<DpMskDO> dpMskOuterList(DpMskPageReqVO pageReqVO) {
        return dpMskMapper.selectRemCountNoZeroPage(pageReqVO);
    }

    @Override
    public void dpMskOutStroe(DispatchVehicleSaveReqVO createReqVO) {
        //修改当前单的数据
        List<DpMskDO> dpMskDOList= createReqVO.getDpMskDOList();
        //修改运表单数据
        for (DpMskDO dpMskDO : dpMskDOList) {
            dpMskDO.setDispatchNumber(createReqVO.getDispatchNumber());
            //设置剩余件数 = 剩余总件数 - 出库件数
            Integer outCount = dpMskDO.getOutCount();
            int remCount = dpMskDO.getRemCount() - (outCount == null ? 0 : outCount);
            if (remCount < 0) {
                throw exception(DP_COUNT_OUTOF_MAX);
            }else {
                dpMskDO.setRemCount(remCount);
            }
            //设置剩余体积 = 剩余总体积 - 出库体积
            Double outVolume = dpMskDO.getOutVolume();
            double remVolume = dpMskDO.getRemVolume() - (outVolume == null ? 0 : outVolume);
            if (remVolume < 0) {
                throw exception(DP_VOLUME_OUTOF_MAX);
            }else {
                dpMskDO.setRemVolume(remVolume);
            }
            //设置剩余重量 = 剩余总重量 - 出库重量
            Double outWeight = dpMskDO.getOutWeight();
            double remWeight = dpMskDO.getRemWeight() - (outWeight == null ? 0 : outWeight);
            if (remWeight < 0) {
                throw exception(DP_WEIGHT_OUTOF_MAX);
            }else {
                dpMskDO.setRemWeight(remWeight);
            }
        }

        //批量修改制单数据
        dpMskMapper.updateById(dpMskDOList);

        //处理配车表数据
        List<DispatchVehicleDO> dispDOs = new ArrayList<DispatchVehicleDO>();
        for (DpMskDO dpMskDO : dpMskDOList) {
            DispatchVehicleDO vehicleDO = BeanUtils.toBean(createReqVO, DispatchVehicleDO.class);
            //处理车数据
            vehicleDO.setDpId(dpMskDO.getId());
            vehicleDO.setNo(dpMskDO.getNo());
            vehicleDO.setDispatchNumber(createReqVO.getDispatchNumber());
            vehicleDO.setInventoryStatus(1);
            // 使用 Gson 将 dpYwDO 转换为 JSON 字符串
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            String dpDataJson = gson.toJson(dpMskDO);  // LocalDateTime 字段会被跳过
            // 设置 JSON 字符串到 createReqVO 的 dpData 字段
            vehicleDO.setDpData(dpDataJson);
            dispDOs.add(vehicleDO);
        }
        // 批量插入配车数据
        dispatchVehicleMapper.insertBatch(dispDOs);

        //插入数据到供应商车队
        List<DispatchVehicleDO> supplierList = createReqVO.getSupplierInfo();
        String dispatchNumber = createReqVO.getDispatchNumber();
        String department = createReqVO.getDepartment();
        //处理时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(new Date());
        createReqVO.setDate(formattedDate);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        String recordDate = sdf2.format(new Date());
        createReqVO.setRecordDate(recordDate);
        createReqVO.setDpMskDOList(null);
        createReqVO.setSupplierInfo(null);
        List<SupplierFleetDO> fleetDOS = new ArrayList<>();
        for (DispatchVehicleDO supplierInfo : supplierList) {
            String fleet = supplierInfo.getFleet();
            if (fleet == null || fleet.trim().equals("")) {
                continue;
            }
            SupplierFleetDO supplierFleetDO = new SupplierFleetDO();
            supplierFleetDO.setType(1);
            supplierFleetDO.setCategory(supplierInfo.getCategory());
            supplierFleetDO.setName(supplierInfo.getSupplier());
            supplierFleetDO.setFleet(fleet);
            supplierFleetDO.setTotalAmount(supplierInfo.getExpense());
            //出库设置币种
            supplierFleetDO.setCurrencyType(supplierInfo.getCurrencyType());
            supplierFleetDO.setRemark(dispatchNumber);
            supplierFleetDO.setDepartment(department);

            // 处理info字段
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            createReqVO.setCategory(supplierInfo.getCategory());
            createReqVO.setSupplier(supplierInfo.getSupplier());
            createReqVO.setFleet(fleet);
            createReqVO.setFare(supplierInfo.getFare());
            createReqVO.setExpense(supplierInfo.getExpense());
            createReqVO.setCurrencyType(supplierInfo.getCurrencyType());
            createReqVO.setRemark(dispatchNumber);
            createReqVO.setDepartment(department);
            String info = gson.toJson(createReqVO);
            supplierFleetDO.setInfo(info);
            fleetDOS.add(supplierFleetDO);
        }
        supplierFleetMapper.insertBatch(fleetDOS);
    }

    // ==================== 子表（ERP莫斯科制单货号详情） ====================

    @Override
    public List<DpItemMskDO> getDpItemMskListByNo(String no) {
        return dpItemMskMapper.selectListByNo(no);
    }

    private void createDpItemMskList(String no, List<DpItemMskDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpItemMskMapper.insertBatch(list);
    }

    private void updateDpItemMskList(String no, List<DpItemMskDO> list) {
        deleteDpItemMskByNo(no);
        createDpItemMskList(no, list);
    }

    private void deleteDpItemMskByNo(String no) {
        dpItemMskMapper.deleteByNo(no);
    }

    @Override
    public List<DispatchVehicleDO> dpMskEnterList(String dispatchNumber, Integer line, Integer inventoryStatus, Integer dest, String dpId) {
        return dispatchVehicleMapper.selectByDispatch(dispatchNumber, line, inventoryStatus, dest,dpId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enterStroeDpMsk(List<DispatchVehicleSaveReqVO> pageReqVO) {
        List<DispatchVehicleDO> list = BeanUtils.toBean(pageReqVO, DispatchVehicleDO.class);
        for (DispatchVehicleDO dispatchVehicleDO : list) {
            String dpData= dispatchVehicleDO.getDpData();
            JSONObject jsonObject = JSONObject.parseObject(dpData);
            DpMskDO dpMskDO = JSONObject.toJavaObject(jsonObject, DpMskDO.class);

            dpMskDO.setRemCount((Integer) jsonObject.get("outCount"));
            BigDecimal outVolume = jsonObject.getBigDecimal("outVolume");
            dpMskDO.setRemVolume(outVolume.doubleValue());
            BigDecimal outWeight = jsonObject.getBigDecimal("outWeight");
            dpMskDO.setRemWeight(outWeight.doubleValue());
            DpMskDO dpMskDO1 = dpMskMapper.selectById(dpMskDO.getId());
            dpMskDO.setInventoryStatus(2);
            if (dpMskDO1 != null) {
                dpMskDO.setRemCount(dpMskDO.getRemCount() + dpMskDO1.getRemCount());
                dpMskDO.setRemVolume(dpMskDO.getRemVolume() + dpMskDO1.getRemVolume());
                dpMskDO.setRemWeight(dpMskDO.getRemWeight() + dpMskDO1.getRemWeight());
                dpMskMapper.updateById(dpMskDO);
            } else {
                dpMskMapper.insert(dpMskDO);
            }

            dpMapper.enterDpStart(dpMskDO.getId());

            dispatchVehicleMapper.updateById(dispatchVehicleDO.setInventoryStatus(2));

            dpServiceImpl.arrDataDpUpdata(dpMskDO.getId(),(Integer) jsonObject.get("outCount"),outVolume.doubleValue(),outWeight.doubleValue());
        }
    }

    @Override
    public void signDp(DpMskSaveReqVO updateReqVO) {
        Integer signNum = updateReqVO.getSignNum();
        Integer num = updateReqVO.getNum();
        Integer reCount = updateReqVO.getRemCount();
        int signCount = signNum + num;

        DpMskDO dpMskDO = BeanUtils.toBean(updateReqVO, DpMskDO.class);
        dpMskDO.setSignNum(signCount);
        if (signCount == reCount) {
            dpMskDO.setPickStatus(1);
        }
        dpMskMapper.updateById(dpMskDO);

        String id = updateReqVO.getId();
        updateReqVO.setId(null);
        DpSignDO dpSignDO = BeanUtils.toBean(updateReqVO, DpSignDO.class);
        dpSignDO.setDpId(id);
        dpSignDO.setSignNum(updateReqVO.getNum());
        dpSignDO.setStoreType(11);

        dpSignMapper.insert(dpSignDO);

//        if(updateReqVO.getSignStatus()==2){
//            dpServiceImpl.updateDpData(updateReqVO.getId());
//        }
    }
    
}